#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#include <poll.h>

#include "common.h"

#define FILE_EXIT_NO -1
#define FILE_EXIT_YES 0

#define GET_POWER_SIGNAL    "1"


/** 判断文件是否存在 */
void isExit() {
    int ret = access(SYSFS_GPIO_RST_VAL, F_OK);
    if(FILE_EXIT_NO == ret) {
        LOG_DEBUG("create gpio power keep off \n");
        //对引脚 389 的设置
        system("echo 389 > /sys/class/gpio/export");            //创建引脚
        system("echo in > /sys/class/gpio/gpio389/direction");  //设置引脚低电平
        system("echo both > /sys/class/gpio/gpio389/edge");     //设置引脚可中断
    }
}

/****
 * 
 *  基于用户态操作 GPIO 引脚 
 * 
 *  1. 查询   2. 中断
 * 
 *  gpio的打开操作在shell脚本当中写
 * 
 * 这里只负责对已存在的引脚 做查询和中断处理
 * 
 */
//查询 - 这种方式不能应用于监听的场景, 测试之后, 当引脚值发生改变时, 这里读出的值依然是第一次读取的值
int gpio_select() {
    isExit();
    int fd = open(SYSFS_GPIO_RST_VAL, O_RDONLY);
    uint8 res[4];
    if(fd == -1) {
        LOG_DEBUG("#ERR: -GPIO ERROR- error to open %s \n", SYSFS_GPIO_RST_VAL);
        return KT_ERROR;
    }

    while (1)
    {
        if(-1 == read(fd, &res, sizeof(res))) {
            LOG_DEBUG("#ERR: -GPIO ERROR- error to read path %s", SYSFS_GPIO_RST_VAL);
            return KT_ERROR;
        }
        //todo
        LOG_DEBUG("keppof----------> %c \n", res[0]);
        usleep(200*1000); //10ms
    }
}

// 中断
int gpio_break() {
    isExit();
    int fd = open(SYSFS_GPIO_RST_VAL, O_RDONLY);
    uint8 res[4];
    int len;
    if(fd == -1) {
        LOG_DEBUG("#ERR: -GPIO ERROR- error to open %s \n", SYSFS_GPIO_RST_VAL);
        return KT_ERROR;
    }

    struct pollfd fds[1];
    fds[0].fd = fd;
    fds[0].events = POLLPRI;

    while (1)
    {
        if(-1 == poll(fds, 1, 0)) {
            LOG_ERROR("#ERR: -GPIO ERROR- error to poll fd, fd: %d \n", fds[0].fd);
        }
        
        if(fds[0].revents & POLLPRI) {
            if(-1 == lseek(fd, 0, SEEK_SET)) {
                LOG_ERROR("#ERR: -GPIO ERROR- error to lseek fd, fd %d \n", fds[0].fd);
            }

            if(-1 == (len = read(fd, res, sizeof(res)))) {
                LOG_ERROR("#ERR: -GPIO ERROR- error to read fd, fd %d \n", fds[0].fd);
            }
            //todo 符合条件则做以下操作
            if(res[0]=='1') {
                return KT_OK;
            }
            usleep(10*1000); //10ms
        }
    }
    return KT_ERROR;
}